package com.ruoyi.web.controller.mail;

import com.jianqiao.delivery.enums.MailSendTypeEnum;
import com.jianqiao.delivery.mail.AESUtil;
import com.jianqiao.delivery.mail.CodeUtil;
import com.jianqiao.delivery.mail.service.impl.EmailServiceImpl;
import com.jianqiao.delivery.mail.domain.RegisterEntity;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.RegisterBody;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.framework.web.service.SysRegisterService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * author: cyx
 * create: 2024/11/22 11:44
 **/
@Slf4j
@RestController
@RequestMapping("/gmail")
public class GmailController {

    @Autowired
    private EmailServiceImpl emailServiceImpl;

    @Autowired
    private CodeUtil codeUtil;

    @Autowired
    private SysRegisterService registerService;

    @Autowired
    private SysLoginService loginService;

    @Autowired
    private RedisCache redisCache;

    @PostMapping("/send")
    public AjaxResult send(@RequestBody Map<String ,String> paramMap) {
        String email = paramMap.get("email");
        String type = paramMap.get("type");

        List<String> enumList = MailSendTypeEnum.getAllValues();
        if (!enumList.contains(type)) {
            log.error("传入的type错误，请核对 MailSendTypeEnum 中的value值");
            return AjaxResult.error("Something went wrong, please try again later or contact the staff");
        }
        if (!paramMap.containsKey("type")) {
            log.error("请传入type值");
            return AjaxResult.error("Something went wrong, please try again later or contact the staff");
        }

        log.info("邮箱准备发送邮件");
        // 生成验证码
        String code = String.valueOf(codeUtil.generateVerificationCode());
        try {
            // 使用AES加密验证码
            String encryptedCode = AESUtil.encrypt(code);

            emailServiceImpl.sendHtmlMail(email ,"邮箱验证" ,encryptedCode ,type);

            // 存储验证码到redis,设置过期时间为 5 分钟
            redisCache.deleteObject(email);
            redisCache.setCacheObject(email,code,5,TimeUnit.MINUTES);

            log.info("邮箱发送邮件结束");
            return AjaxResult.success();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     *  网页注册的邮箱验证，成功后自动注册
     */
    @PostMapping("/verifyCode")
    public AjaxResult verifyCode(@RequestBody RegisterEntity registerEntity){

        log.info("进入验证码校验");

        // 从redis获取验证码
        String originCode = redisCache.getCacheObject(registerEntity.getEmail());

        // 浏览器会自动将base64的验证码里的加号替换为空格，这里需替换空格回加号
        String base64Code = registerEntity.getCode();
        base64Code = base64Code.replace(' ', '+');

        try {
            // 使用AES解密验证码
            String decryptedCode = AESUtil.decrypt(base64Code);
            // 比较解码和原始验证码
            if (!decryptedCode.equals(originCode)){
                redisCache.deleteObject(registerEntity.getEmail());
                log.error("校验验证码失败");
                return AjaxResult.error("验证失败");
            } else {
                redisCache.deleteObject(registerEntity.getEmail());
            }

            // 邮箱地址做用户名
            String emailAsUsername = registerEntity.getEmail();

            // 用户注册
            RegisterBody registerBody = new RegisterBody();
            registerBody.setUsername(emailAsUsername);
            registerBody.setPassword(registerEntity.getPassword());
            String msg = registerService.gmailRegister(registerBody);
            System.out.println(msg);

            // 用户登录
            AjaxResult ajax = AjaxResult.success();
            String password = registerEntity.getPassword();
            // 生成令牌
            String token = loginService.gmailLogin(emailAsUsername, password);
            ajax.put(Constants.TOKEN, token);

            return ajax;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
